package com.uinnova.product.eam.web.asset.peer;

import com.binary.core.util.BinaryUtils;
import com.binary.jdbc.Page;
import com.uinnova.product.cj.feign.dto.PlanDesignInstanceDTO;
import com.uinnova.product.eam.model.CiUpAndDownCdt;
import com.uinnova.product.eam.model.VcCiClassInfoDto;
import com.uinnova.product.eam.model.VcCiRltInfo;
import com.uinnova.product.eam.model.diagram.DiagramNodeLinkInfo;
import com.uinnova.product.eam.model.dto.EamAppConfigDto;
import com.uinnova.product.eam.model.vo.*;
import com.uinnova.product.eam.service.ICIRltSwitchSvc;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.asset.AppConfigSvc;
import com.uinnova.product.eam.service.asset.AppSystemSvc;
import com.uinnova.product.eam.service.utils.VisualModelUtils;
import com.uinnova.product.eam.web.asset.bean.HtAppSystemRltVo;
import com.uino.bean.cmdb.base.*;
import com.uino.bean.cmdb.query.ESCISearchBean;
import com.uino.dao.cmdb.ESVisualModelSvc;
import com.uino.util.sys.SysUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class AppSystemPeer {

    @Resource
    AppSystemSvc appSystemSvc;

    @Resource
    ICISwitchSvc iciSwitchSvc;

    @Resource
    AppConfigSvc appConfigSvc;

    @Resource
    ICIRltSwitchSvc ciRltApiSvc;

    @Resource
    ESVisualModelSvc esVisualModelSvc;


    public Page<ESCIInfo> queryAppSystemList(AppSystemQueryVo queryVo) {
        Page<ESCIInfo> esciInfoPage = appSystemSvc.queryAppSystemList(queryVo);
        return esciInfoPage;
    }

    public ESCIClassInfo getAppSystemClassInfo() {
        ESCIClassInfo appSystemClassInfo = appSystemSvc.getAppSystemClassInfo();
        return appSystemClassInfo;
    }

    public String getCardConfiguration() {
        return appSystemSvc.getCardConfiguration();
    }

    public void saveCardConfiguration(String data) {
        appSystemSvc.saveCardConfiguration(data);
    }

    public VcCiClassInfoDto queryAppSystemClassInfo(Long classId, String like) {
        return appSystemSvc.queryAppSystemClassInfo(classId, like);
    }

    public Page<HtAppSystemRltVo> queryUpAndDownRlt(String ciCode, Integer pageNum, Integer pageSize) {
        CiUpAndDownCdt cdt = new CiUpAndDownCdt();
        Assert.notNull(ciCode,"ciCode不能为空");
        ESCISearchBean esciSearchBean = new ESCISearchBean();
        esciSearchBean.setCiCodes(Collections.singletonList(ciCode));
        Page<ESCIInfo> esciInfoPage = iciSwitchSvc.getCiSvc(LibType.DESIGN).searchESCIByBean(esciSearchBean);
        if(!CollectionUtils.isEmpty(esciInfoPage.getData())){
            cdt.setsCiId(esciInfoPage.getData().get(0).getId());
        }
        ESCIClassInfo appSystemClassInfo = appSystemSvc.getAppSystemClassInfo();
        cdt.setDown(1);
        cdt.setUp(1);
        cdt.setCiClassIds(Collections.singletonList(appSystemClassInfo.getId()));
        List<VcCiRltInfo> vcCiRltInfos = ciRltApiSvc.queryUpAndDownRlt(LibType.DESIGN, cdt.getsCiId(), cdt.getCiClassIds(), cdt.getRltClassIds(), cdt.getUp(), cdt.getDown(), Boolean.TRUE);

        // List<Long> collect = vcCiRltInfos.stream().map(e -> e.getCiRlt().getClassId()).collect(Collectors.toList());
        // List<ESCIClassInfo> esciClassInfos = esRltClassSvc.getListByQuery(QueryBuilders.termsQuery("id", collect));
        // Map<Long, ESCIClassInfo> rltClassMap = esciClassInfos.stream().collect(Collectors.toMap(ESCIClassInfo::getId, e -> e, (k1, k2) -> k2));

        List<Long> rlt = this.queryVisualModelRlt();
        List<HtAppSystemRltVo> result = new ArrayList<>();
        for (VcCiRltInfo vcCiRltInfo : vcCiRltInfos) {
            if (rlt.contains(vcCiRltInfo.getCiRlt().getClassId())) {
                HtAppSystemRltVo htAppSystemRltVo = new HtAppSystemRltVo();
                // ESCIClassInfo classInfo = rltClassMap.get(vcCiRltInfo.getCiRlt().getClassId());

                // htAppSystemRltVo.setRltClassName(classInfo.getClassName());
                htAppSystemRltVo.setRltClassDesc(BinaryUtils.isEmpty(vcCiRltInfo.getAttrs()) ? "-" :
                        BinaryUtils.isEmpty(vcCiRltInfo.getAttrs().get("描述")) ? "-" : vcCiRltInfo.getAttrs().get("描述"));
                // 关系类型新逻辑
                if (vcCiRltInfo.getSourceCiInfo().getCi().getCiCode().equals(ciCode)) {
                    // 源端是当前系统 去目标端数据
                    htAppSystemRltVo.setAppSystemName(BinaryUtils.isEmpty(vcCiRltInfo.getTargetCiInfo().getAttrs().get("中文全称")) ?
                            "-" : vcCiRltInfo.getTargetCiInfo().getAttrs().get("中文全称"));
                    htAppSystemRltVo.setRltClassName("下游提供方");
                } else {
                    // 取源端数据
                    htAppSystemRltVo.setAppSystemName(BinaryUtils.isEmpty(vcCiRltInfo.getSourceCiInfo().getAttrs().get("中文全称")) ?
                            "-" : vcCiRltInfo.getSourceCiInfo().getAttrs().get("中文全称"));
                    htAppSystemRltVo.setRltClassName("上游调用方");
                }
                result.add(htAppSystemRltVo);
            }
        }

        // 手动分页处理查询结果
        List<HtAppSystemRltVo> subInfos = new ArrayList<>();
        int totalRows = result.size();
        int pageStart  = pageNum == 1 ? 0 : (pageNum - 1) * pageSize;       // 截取的开始位置
        int pageEnd = totalRows < pageNum * pageSize ? totalRows : pageNum * pageSize;        // 截取的结束位置
        if(totalRows > pageStart){
            subInfos =result.subList(pageStart, pageEnd);
        }
        int totalPage = result.size() % pageSize == 0 ? result.size() / pageSize : result.size() / pageSize + 1;     // 总页数

        Page<HtAppSystemRltVo> page = new Page<>();
        page.setPageNum(pageNum);      // 页数
        page.setPageSize(pageSize);     // 条数
        page.setTotalRows(totalRows);        // 总行数
        page.setTotalPages(totalPage);       // 总页数
        page.setData(subInfos);     // 分页数据
        return page;
    }

    public List<Long> queryVisualModelRlt(){
        ESCIClassInfo appSystemClassInfo = appSystemSvc.getAppSystemClassInfo();
        Long appSystemId = appSystemClassInfo.getId();
        ESVisualModel esVisualModel = esVisualModelSvc.getEnableModel(SysUtil.getCurrentUserInfo().getDomainId());
        if(BinaryUtils.isEmpty(esVisualModel)){
            return Collections.emptyList();
        }
        //获取元模型中关系
        List<Long> result = new ArrayList<>();
        List<DiagramNodeLinkInfo> rltLinkList = VisualModelUtils.getRltClassIds(esVisualModel);
        for (DiagramNodeLinkInfo link : rltLinkList) {
            if(appSystemId.equals(link.getSourceId()) && appSystemId.equals(link.getTargetId())){
                result.add(link.getLinkId());
            }
        }
        return result;
    }

    public List<AppSystemQueryConVo> getQueryConditions() {
        return appSystemSvc.getQueryConditions();
    }

    public AppArchWallConfigVo getAppArchWallConfig() {
        return appSystemSvc.getAppArchWallConfig();
    }

    public List<AppSystemAssetsVo> getSystemAssets(String ciCode) {
        return appSystemSvc.getSystemAssets(ciCode);
    }

    public Page<PlanDesignInstanceDTO> getSystemPlan(Integer pageNum, Integer pageSize, String ciCode) {


        Page<PlanDesignInstanceDTO> systemPlan = appSystemSvc.getSystemPlan(pageNum, pageSize, ciCode);
        return systemPlan;
    }

    public Long saveFilterConfig(EamAppConfigDto appSysConfig) {
        return appConfigSvc.saveFilterConfig(appSysConfig);
    }

    public EamAppConfigVo queryFilterConfig(String classCode,Long cardId) {
        return appConfigSvc.queryFilterConfig(classCode,cardId);
    }

    public AppSysQueryVo queryAppSystemListNew(AppSystemQueryVo queryVo, LibType libType) {
        return appSystemSvc.queryAppSystemListNew(queryVo,libType);
    }

    public List<ESCIAttrDefInfo> getDefInfoByClassCode(String classCode) {
        return appSystemSvc.getDefInfoByClassCode(classCode);
    }

    public ResponseEntity<byte[]> exportBySearch(AppSystemQueryVo queryVo, LibType libType) {
        return appSystemSvc.exportBySearch(queryVo,libType);
    }

}
